package com.doublefish.doublefishrobot.ui.video.utils;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.doublefish.doublefishrobot.R;
import com.doublefish.doublefishrobot.ui.video.bean.VideoInfoBean;
import com.doublefish.doublefishrobot.ui.video.bean.VideoPlayerItemBean;
import com.doublefish.doublefishrobot.ui.video.utils.videocache.CacheListener;
import com.doublefish.doublefishrobot.ui.video.utils.videocache.HttpProxyCacheServer;
import com.doublefish.doublefishrobot.ui.video.utils.videocache.file.FileCache;
import com.doublefish.doublefishrobot.ui.video.utils.videocache.file.FileNameGenerator;
import com.doublefish.doublefishrobot.utils.SharedPreferencesUtils;
import com.doublefish.doublefishrobot.utils.ToastUtil;
import com.doublefish.doublefishrobot.utils.db.DataBaseApi;
import com.doublefish.doublefishrobot.utils.network.NetworkReachabilityUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * 作者:dugaofeng on 2024/10/29 15:16
 */
public class VideoManager {
    //视频错误类型
    public static final int DFVideoSourceError_None = 0;            //视频信息为空
    public static final int DFVideoSourceError_Need_Download = 1;   //本地视频不存在，需要下载
    public static final int DFVideoSourceError_NetError = 2;        //网络错误，无法下载(没有网络)
    public static final int DFVideoSourceError_Downloading = 3;     //下载中
    public static final int DFVideoSourceError_Download_Error = 4;  //下载失败
    //视频的来源类型
    public static final int DFGetVideoSourceType_Auto = 0;           //未选择，视 缓存情况/网络情况 而定
    public static final int DFGetVideoSourceType_NORMAL_FORCE = 1;   //强制播放标清视频
    public static final int DFGetVideoSourceType_HD_NEED = 2;        //需要播放高清视频
    public static final int DFGetVideoSourceType_HD_FORCE = 3;       //强制播放高清视频
    public static final int DFGetVideoSourceType_EDITED = 99;        //对比播放页面，编辑后的视频

    private Context context;

    private List<VideoInfoBean> videoInfoBeanList = new ArrayList<>();
    private boolean didInitData = false;

    private static String HD_NAME_PREFIX = "HD_";
    private static String ND_NAME_PREFIX = "ND_";

    private Handler uiHandler = new Handler(Looper.getMainLooper());

    private VideoManager() {

    }

    //单例
    private static volatile VideoManager instance;

    public static VideoManager getInstance() {
        if (instance == null) {
            synchronized (VideoManager.class) {
                if (instance == null) {
                    instance = new VideoManager();
                }
            }
        }
        return instance;
    }

    //region  视频数据库
    //使用前必须先初始化
    public void init(Context applicationContext, OnDatabaseInitListner listner) {
        this.context = applicationContext;

        if (didInitData) {
            if (listner != null) {
                listner.onCallback(true);
            }
        } else {
            didInitData = true;
            //创建文件夹
            makeVideoDirs();
            //清空临时文件夹
            clearTempDirs();
            //加载视频数据
            loadData(listner);
        }
    }

    //加载视频数据
    private void loadData(OnDatabaseInitListner listner) {
        loadDataFromDB(listner);
    }

    private void loadDataFromDB(OnDatabaseInitListner listner) {
        DataBaseApi.queryVideoList(new DataBaseApi.OnQueryVideoListListner() {
            @Override
            public void onCallback(boolean suc, List<VideoInfoBean> list) {
                if (suc) {
                    if (list == null) {
                        loadDataFromJson(listner);
                    } else {
                        videoInfoBeanList = list;
                    }
                }
                if (listner != null) {
                    listner.onCallback(suc);
                }
            }
        });
    }

    //从本地Assets中读取文件
    private void loadDataFromJson(OnDatabaseInitListner listner) {
        try {
            InputStream inputStream = context.getResources().getAssets().open("df_video.json");
            int length = inputStream.available();
            byte[] buff = new byte[length];
            inputStream.read(buff);
            inputStream.close();

            String json = new String(buff, StandardCharsets.UTF_8);
            List<VideoInfoBean> list = JSON.parseArray(json, VideoInfoBean.class);

            for (VideoInfoBean infoBean : list) {
                if (infoBean.isHD()) {
                    infoBean.setTempPath(getTempVideoDir() + HD_NAME_PREFIX + infoBean.getCode() + ".mp4");
                    infoBean.setLocalPath(getHDVideoDir() + infoBean.getCode() + ".mp4");
                } else {
                    infoBean.setTempPath(getTempVideoDir() + ND_NAME_PREFIX + infoBean.getCode() + ".mp4");
                    infoBean.setLocalPath(getVideoDir() + infoBean.getCode() + ".mp4");
                }
            }

            if (list.size() > 0) {
                saveVideosToDB(list, new DataBaseApi.OnDatabaseCommonListner() {
                    @Override
                    public void onCallback(boolean suc) {
                        if (suc) {
                            loadDataFromDB(listner);
                        } else {
                            if (listner != null) {
                                listner.onCallback(false);
                            }
                        }
                    }
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
            if (listner != null) {
                listner.onCallback(false);
            }
        }
    }

    private void saveVideoToDB(VideoInfoBean bean, DataBaseApi.OnDatabaseCommonListner listner) {
        DataBaseApi.saveVideo(bean, listner);
    }

    private void saveVideosToDB(List<VideoInfoBean> list, DataBaseApi.OnDatabaseCommonListner listner) {
        DataBaseApi.saveVideos(list, listner);
    }


    //全部数据
    public List<VideoInfoBean> getVideoInfoBeanList() {
        return videoInfoBeanList;
    }

    //过滤掉一半的数据
    public List<VideoInfoBean> getVideoInfoBeanListIgnoreHD() {
        List<VideoInfoBean> list = new ArrayList<>();
        for (VideoInfoBean bean : videoInfoBeanList) {
            if (!bean.isHD()) {
                list.add(bean);
            }
        }
        return list;
    }

    //有视频的数据
    public List<VideoInfoBean> getVideoInfoBeanListExistVideo() {
        List<VideoInfoBean> list = new ArrayList<>();
        for (VideoInfoBean bean : videoInfoBeanList) {
            if (bean.getIsExistVideo() == 99) {
                list.add(bean);
            }
        }
        return list;
    }

    //根据code获取模型
    public VideoInfoBean getVideoInfoBean(String videoCode, boolean isHD) {
        for (VideoInfoBean bean : videoInfoBeanList) {
            if (bean.isHD() == isHD && bean.getCode().equals(videoCode)) {
                return bean;
            }
        }
        return null;
    }

    //endregion

    //region  文件操作
    //创建文件夹
    private void makeVideoDirs() {
        try {
            //临时普清文件夹
            File tempDir = new File(getTempVideoDir());
            tempDir.mkdirs();
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            //普清文件夹
            File videoDir = new File(getVideoDir());
            videoDir.mkdirs();
        } catch (Exception e) {
            e.printStackTrace();
        }
//        try {
//            //临时高清文件夹
//            File tempHDDir = new File(getTempHDVideoDir());
//            tempHDDir.mkdirs();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        try {
            //高清文件夹
            File hdDir = new File(getHDVideoDir());
            hdDir.mkdirs();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            //编辑后视频存储的临时路径
            File editCacheDir = new File(getEditCacheVideoDir());
            editCacheDir.mkdirs();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //清空临时文件夹
    private void clearTempDirs() {
        //临时普清文件夹
        File tempDir = new File(getTempVideoDir());
        File[] tempFiles = tempDir.listFiles();
        if (tempFiles != null && tempFiles.length > 0) {
            for (File file : tempFiles) {
                file.delete();
            }
        }
//        //临时高清文件夹
//        File tempHDDir = new File(getTempHDVideoDir());
//        File[] tempHDFiles = tempHDDir.listFiles();
//        if (tempHDFiles != null && tempHDFiles.length > 0) {
//            for (File file : tempHDFiles) {
//                file.delete();
//            }
//        }
        // 编辑后视频存储的临时路径
        File editCacheDir = new File(getEditCacheVideoDir());
        File[] editCacheFiles = editCacheDir.listFiles();
        if (editCacheFiles != null && editCacheFiles.length > 0) {
            for (File file : editCacheFiles) {
                file.delete();
            }
        }
    }

    //将视频从临时文件夹移动到正式文件夹
    private boolean moveVideo(String fromPath, String toPath) {
//        try {
//            File toFile = new File(toPath);
//            if (toFile.exists()) {
//                toFile.delete();
//            }
//
//            //移动文件
//            File fromFile = new File(fromPath);
//            if (fromFile.exists()) {
//                return fromFile.renameTo(toFile);
//            }
//
//            File fromFile2 = new File(fromPath + FileCache.TEMP_POSTFIX);
//            if (fromFile2.exists()) {
//                return fromFile2.renameTo(toFile);
//            }
//            return false;
//        } catch (Exception e) {
//            e.printStackTrace();
//            return false;
//        }

        try {
            //移动文件
            File fromFile = new File(fromPath);
            if (fromFile.exists()) {
                File toFile = new File(toPath);
                if (toFile.exists()) {
                    toFile.delete();
                }
                return fromFile.renameTo(toFile);
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //删除文件
    private boolean deleteFile(String path) {
        try {
            File file = new File(path);
            if (file.exists()) {
                return file.delete();
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取普清视频路径
     */
    public String getVideoDir() {
        //外部路径
        String dirPath = rootPath() + "/doublefish_video/video/";
        return dirPath;
    }

    /**
     * 获取普清临时视频路径
     */
    public String getTempVideoDir() {
        //外部路径
        String dirPath = rootPath() + "/doublefish_video/temp/";
        return dirPath;
    }

    /**
     * 获取高清视频路径
     */
    public String getHDVideoDir() {
        //外部路径
        String dirPath = rootPath() + "/doublefish_video/hdvideo/";
        return dirPath;
    }

//    /**
//     * 获取高清临时视频路径
//     */
//    public String getTempHDVideoDir() {
//        //外部路径
//        String dirPath = rootPath() + "/doublefish_video/hdtemp/";
//        return dirPath;
//    }

    /**
     * 获取编辑后视频存储的临时路径
     */
    public String getEditCacheVideoDir() {
        //外部路径
        String dirPath = rootPath() + "/doublefish_video/editcache/";
        return dirPath;
    }

    //指定路径是否存在
    public boolean fileIsExistOfPath(String path) {
        File file = new File(path);
        return file.exists();
    }

    private String rootPath() {
        // FIXME: 2025/1/21 修改本地目录
        //由于部分机型( API29（Android 10）) 使用Environment.getExternalStorageDirectory() 时，会dir.mkdirs()失败
        //改为使用 context.getExternalFilesDir(null)
//        String rootPath = Environment.getExternalStorageDirectory().toString();
        String rootPath = context.getExternalFilesDir(null).toString();
        return rootPath;
    }

    //endregion


    //region 视频源
    public void getPlayerVideo(String videoCode, int getVideoSourceType, OnGetPalyerVideoListner listner) {
        if (listner == null) {
            Log.e("getgetPlayerVideo", "OnGetPalyerVideoListner 不能为空");
            return;
        }
        if (TextUtils.isEmpty(videoCode)) {
            listner.onFail(DFVideoSourceError_None);
            return;
        }
        if (videoInfoBeanList.size() == 0) {
            listner.onFail(DFVideoSourceError_None);
            return;
        }

        //根据videoCode找到数据
        VideoInfoBean hdBean = null;
        VideoInfoBean normalBean = null;
        for (VideoInfoBean bean : videoInfoBeanList) {
            if (bean.getCode().equals(videoCode) && bean.isHD()) {
                hdBean = bean;
            }
            if (bean.getCode().equals(videoCode) && !bean.isHD()) {
                normalBean = bean;
            }
        }
        if (normalBean == null && hdBean == null) {
            listner.onFail(DFVideoSourceError_None);
            return;
        }

        if (hdBean.getIsExistVideo() == 99) {
            //本地 有下载的高清视频
            VideoPlayerItemBean itemBean = new VideoPlayerItemBean(VideoPlayerItemBean.DFAVPlayerItemLocal, videoCode, hdBean.getLocalPath(), hdBean.getTime(), hdBean.getSize());
            listner.onSuccess(hdBean, itemBean);
            return;
        }
        if (getVideoSourceType == DFGetVideoSourceType_HD_FORCE) {
            //强制需要高清视频
            //返回值  0.无网络  1.有WIFi  2.有移动网络或其他网络（无wifi）
            int reachability = NetworkReachabilityUtils.networkReachability(context);
            if (reachability == 0) {
                //0.无网络
                listner.onFail(DFVideoSourceError_NetError);
                return;
            }
            //下载高清视频
            downloadVideo(hdBean, listner);
            return;
        }

        if (getVideoSourceType == DFGetVideoSourceType_HD_NEED) {
            //需要高清视频
            //返回值 0.无网络  1.有WIFi  2.有移动网络或其他网络（无wifi）
            int reachability = NetworkReachabilityUtils.networkReachability(context);
            if (reachability == 0) {
                //没有网络
                listner.onFail(DFVideoSourceError_NetError);
                return;
            }

            //视频下载时的网络设置 0.仅WiFi（默认） 1.WiFi和移动网络
            int videoDownloadType = SharedPreferencesUtils.getInstant().getVideoDownloadType();
            if (videoDownloadType == 0 && reachability == 2) {
                ////仅WiFi下载,移动网络要提示流量
                listner.onFail(DFVideoSourceError_Need_Download);
                return;
            }
            //下载高清视频
            downloadVideo(hdBean, listner);
            return;
        }

        if (normalBean.getIsExistVideo() == 99) {
            //本地 有下载的标清视频
            VideoPlayerItemBean itemBean = new VideoPlayerItemBean(VideoPlayerItemBean.DFAVPlayerItemLocal, videoCode, normalBean.getLocalPath(), normalBean.getTime(), normalBean.getSize());
            listner.onSuccess(normalBean, itemBean);
            return;
        }

        //返回值 0.无网络  1.有WIFi  2.有移动网络或其他网络（无wifi）
        int reachability = NetworkReachabilityUtils.networkReachability(context);
        if (reachability == 0) {
            //没有网络
            listner.onFail(DFVideoSourceError_NetError);
            return;
        }

        if (getVideoSourceType == DFGetVideoSourceType_NORMAL_FORCE) {
            //强制下载标清视频
            downloadVideo(normalBean, listner);
            return;
        }

        //视频下载时的网络设置 0.仅WiFi（默认） 1.WiFi和移动网络
        int videoDownloadType = SharedPreferencesUtils.getInstant().getVideoDownloadType();
        if (videoDownloadType == 0 && reachability == 2) {
            ////仅WiFi下载,移动网络要提示流量
            listner.onFail(DFVideoSourceError_Need_Download);
            return;
        }

        //下载标清视频
        downloadVideo(normalBean, listner);
    }
//
//    //下载视频
//    private boolean playFlag = true;
//
//    private void downloadVideo(VideoInfoBean videoInfoBean, OnGetPalyerVideoListner listner) {
//
//       if (true) {
//           downloadVideo2(videoInfoBean, listner);
//           return;
//       }
//
//        //返回一个tips 视频下载中
//        listner.onFail(DFVideoSourceError_Downloading);
//        playFlag = true;
//        VideoPlayerItemBean itemBean = new VideoPlayerItemBean(VideoPlayerItemBean.DFAVPlayerItemDownloadAndPlay, videoInfoBean.getCode(), videoInfoBean.getTempPath(), videoInfoBean.getTime(), videoInfoBean.getSize());
//        //download
//        OKHttpApi.downloadFile(context, videoInfoBean.getUrl(), videoInfoBean.getTempPath(), new OKHttpApi.OkHttpFileDownloadCallback() {
//            @Override
//            public void onNetworkPermissionError() {
//                showNetworkPermissionAlert();
//            }
//
//            @Override
//            public void onDownloadProgress(long size) {
////                itemBean.setCacheSize(size);
//                //边下边播  至少下载了1000kb的数据
//                //如果数据太小（<1000000）就等下载完毕在播
//                if (playFlag && itemBean.getSize() >= 1000000 && size > 1000000) {
//                    //通知开始播放
//                    playFlag = false;
//                    //主线程 回调数据
//                    activity.runOnUiThread(new Runnable() {
//                        @Override
//                        public void run() {
//                            listner.onSuccess(videoInfoBean, itemBean);
//                        }
//                    });
//                }
//            }
//
//            @Override
//            public void onDownloadCallback(boolean success, String path, String msg) {
//                if (!success) {
//                    //主线程 回调数据
//                    activity.runOnUiThread(new Runnable() {
//                        @Override
//                        public void run() {
//                            listner.onFail(DFVideoSourceError_Download_Error);
//                        }
//                    });
//                    return;
//                }
//                //更新 保存的视频信息
//                videoInfoBean.setIsExistVideo(99);
//                saveVideoToDB(videoInfoBean, null);
//                //将视频从临时文件夹移动到正式文件夹
//                moveVideo(videoInfoBean.getTempPath(), videoInfoBean.getLocalPath());
//
//                //返回最新数据
//                itemBean.update(VideoPlayerItemBean.DFAVPlayerItemLocal, videoInfoBean.getLocalPath());
//
//                //主线程 回调数据
//                activity.runOnUiThread(new Runnable() {
//                    @Override
//                    public void run() {
//                        listner.onSuccess(videoInfoBean, itemBean);
//                    }
//                });
//            }
//        });
//    }

    public void clearVideos(List<VideoInfoBean> list, OnClearVideosListner listner) {
        if (listner == null) {
            return;
        }
        if (list == null || list.size() == 0) {
            listner.onClearVideos(true);
            return;
        }
        for (VideoInfoBean bean : list) {
            bean.setIsExistVideo(0);
        }
        // 这里必须先写数据库，防止出现视频删了， 但是数据库更新出错的情况（虽然理论上概率极低）
        saveVideosToDB(list, new DataBaseApi.OnDatabaseCommonListner() {
            @Override
            public void onCallback(boolean suc) {
                if (!suc) {
                    listner.onClearVideos(false);
                    return;
                }
                //删掉视频
                for (VideoInfoBean bean : list) {
                    boolean ret = deleteFile(bean.getLocalPath());
                    if (!ret) {
                        //再删一次,删不掉就算了
                        deleteFile(bean.getLocalPath());
                    }
                }
                listner.onClearVideos(true);
            }

            ;
        });
    }

    private void showNetworkPermissionAlert() {
//        String title = "网络错误";
//        String msg = "请检查网络";
//        CommonDialog dialog = new CommonDialog(context, title, msg, null);
//        dialog.setShowNegativeButton(false);
//        dialog.show();

        ToastUtil.showToast(context, context.getString(R.string.network_error));
    }

    //endregion


    //region 视频的边下边播 用HttpProxyCacheServer做一个本地服务进行下载
    private HttpProxyCacheServer proxy = null;
    private MyFileNameGenerator generator = null;

    //视频的边下边播
    private void downloadVideo(VideoInfoBean videoInfoBean, OnGetPalyerVideoListner listner) {
        //初始化 proxy
        if (generator == null) {
            generator = new MyFileNameGenerator();
        }
        if (proxy == null) {
            proxy = new HttpProxyCacheServer.Builder(context)
//                //设置缓存路径
                    .cacheDirectory(new File(getTempVideoDir()))
//                //设置缓存的名称
                    .fileNameGenerator(generator)
                    .build();
        }

        //设置文件名缓存
        generator.setVideoInfoBean(videoInfoBean);

        //返回一个tips 视频下载中
        listner.onFail(DFVideoSourceError_Downloading);
        String remoteUrl = videoInfoBean.getUrl();
        //将远程地址  转化为 本地服务地址
        String localUrl = proxy.getProxyUrl(remoteUrl);
        VideoPlayerItemBean itemBean = new VideoPlayerItemBean(VideoPlayerItemBean.DFAVPlayerItemDownloadAndPlay, videoInfoBean.getCode(), localUrl, videoInfoBean.getTime(), videoInfoBean.getSize());
        itemBean.setProgress(0);

        //先返回地址 出发播放器的下载缓存
        uiHandler.post(new Runnable() {
            @Override
            public void run() {
                listner.onSuccess(videoInfoBean, itemBean);
            }
        });

        //监听  缓存进度
        CacheListener cacheListener = new CacheListener() {
            @Override
            public void onCacheAvailable(File cacheFile, String url, int percentsAvailable) {
                Log.i("cacheFile", url + "   " + percentsAvailable);
                if (percentsAvailable >= 100 && !cacheFile.getName().contains(FileCache.TEMP_POSTFIX)) {
                    //缓存完毕
                    itemBean.setProgress(100);
                    //更新 保存的视频信息
                    videoInfoBean.setIsExistVideo(99);

                    //将视频从临时文件夹移动到正式文件夹
                    boolean move = moveVideo(videoInfoBean.getTempPath(), videoInfoBean.getLocalPath());
                    if (move) {
                        saveVideoToDB(videoInfoBean, null);
                        //返回最新数据
                        itemBean.update(VideoPlayerItemBean.DFAVPlayerItemLocal, videoInfoBean.getLocalPath());
                    }
                } else {
                    //缓存中
                    itemBean.setProgress(percentsAvailable);
                }
                uiHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        listner.onSuccess(videoInfoBean, itemBean);
                    }
                });
            }
        };
        proxy.registerCacheListener(cacheListener, remoteUrl);

    }

    public class MyFileNameGenerator implements FileNameGenerator {

        VideoInfoBean videoInfoBean;

        public void setVideoInfoBean(VideoInfoBean videoInfoBean) {
            this.videoInfoBean = videoInfoBean;
        }

        @Override
        public String generate(String url) {
            if (videoInfoBean.isHD()) {
                return HD_NAME_PREFIX + videoInfoBean.getCode() + ".mp4";
            } else {
                return ND_NAME_PREFIX + videoInfoBean.getCode() + ".mp4";
            }
        }
    }

    //endregion


    //region  callback

    //视频数据库初始化的callback
    public interface OnDatabaseInitListner {
        void onCallback(boolean suc);
    }

    //获取播放器视频数据的callback
    public interface OnGetPalyerVideoListner {
        void onSuccess(VideoInfoBean videoInfoBean, VideoPlayerItemBean itemBean);

        void onFail(int videoSourceError);
    }

    public interface OnClearVideosListner {
        void onClearVideos(boolean suc);
    }

    //endregion


}
